package gw.com.android.presenter.http;

import android.text.TextUtils;
import android.util.Log;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import gw.com.android.app.GTConfig;
import gw.com.android.model.ConfigType;
import gw.com.android.model.ConfigUtil;
import gw.com.android.ui.onlive.Comment;
import gw.com.android.ui.onlive.DiscussData;
import gw.com.android.utils.CacheUtils;
import okhttp3.Request;
import okhttp3.Response;
import www.com.library.interfaces.ReqCallBack;

/**
 * @author jett
 * @since 2017-12-13.
 */
public class DiscussRequest {

    private static final int PAGE_SIZE = 10;

    private int currPage = 1;
    private boolean ifSearchUserPost = false;// 是否查询当前用户的帖子
    private int totalSize;
    private String userNo;//gts2740
    private String accountNo;//60052740

    /**
     * 获取，全部帖子的 缓存（第一页的十条）
     *
     * @param currentTradeType 当前查询的类型
     * @param userNo           如果查询的是分析师的帖子，那么还要传入该分析师的唯一标识; q其他情况
     * @return
     */
    public List<DiscussData> fetchLocal(int currentTradeType, String userNo) {// 这里之所以要传入 分析师userNo，是因为流程中是先获取本地缓存用于加载数据，所以必须传
        this.currentTradeType = currentTradeType;
        String str = CacheUtils.readFile(getCacheFileName(userNo));
        return parse(str, false, userNo);
    }

    private int currentTradeType;//当前的帖子类型
    public final static int TRADE_TYPE_ALL = 0x01;//全部
    public final static int TRADE_TYPE_ANALYST = 0x02;//分析师晒单
    public final static int TRADE_TYPE_GUEST = 0x03;// 客户晒单
    public final static int TRADE_TYPE_BEST = 0x04;// 精华晒单
    public final static int TRADE_TYPE_USER = 0x05;// 指定用户的晒单   --(查询分析师的观点用)
    public final static int TRADE_TYPE_REPLY = 0x06;// 指定用户的所有回复   -- (查询分析师评论用)
    public final static int TRADE_TYPE_MY_POST = 0x07;//查询我的帖子
    public final static int TRADE_TYPE_ALL_POST = 0x08;//查询全部帖子

    /**
     * 查询用户发帖
     *
     * @param ifSearchUserPostT 是否查询用户发帖
     */
    public void getList(final ReqCallBack<List<DiscussData>> callBack, int tradeType, boolean ifSearchUserPostT, String accountNo) {
        ifSearchUserPost = ifSearchUserPostT;
        this.accountNo = accountNo;
        getList(callBack, tradeType, userNo);
    }

    /**
     * @param callBack
     * @param tradeType
     * @param userNo    分析师userNo
     */
    public void getList(final ReqCallBack<List<DiscussData>> callBack, int tradeType, String userNo) {
        currentTradeType = tradeType;
        this.userNo = userNo;
        currPage = 1;
        sendRequest(callBack);
    }

    /**
     * 获取下一页
     */
    public void nextPage(ReqCallBack<List<DiscussData>> callBack) {
        currPage++;
        sendRequest(callBack);
    }

    public boolean hasNextPage() {
        if (totalSize > 0) {
            return (totalSize - 1) / PAGE_SIZE > currPage - 1;
        }
        return false;
    }

    /**
     * 获取所有全部类型的帖子
     */
    private void sendRequest(final ReqCallBack<List<DiscussData>> callBack) {
        String url = ConfigUtil.instance().getHttpUrlIp(ConfigType.CHAT_URL_TAG) + "/api/showTrade/getShowTradeList";
        Https https = new Https().url(url)
                .addParam("groupType", ConfigUtil.instance().mConfigObject.optString(ConfigType.CHAT_GROUP_TYPE))
                .addParam("pageNo", String.valueOf(currPage))
                .addParam("pageSize", String.valueOf(PAGE_SIZE))
                .addParam("companyId", ConfigUtil.instance().mConfigObject.optString(ConfigType.CHAT_COMPANY_ID_TAG))
                .addParam("platform", "android");

        //根据currentTradeType来决定tradeType应该怎么传
        if (currentTradeType == TRADE_TYPE_ANALYST) {
            //分析师，传1
            https
                    .addParam("tradeType", "1")//1 分析师发的
                    .addParam("type", "0,1");//type：0,1 表示晒单+帖子，也可以单独传0，只有晒单，1，只有帖子
        } else if (currentTradeType == TRADE_TYPE_GUEST) {
            https
                    .addParam("tradeType", "1,2")//1 分析師發的 2 客户发的
                    .addParam("type", "0");// 0晒单
        } else if (currentTradeType == TRADE_TYPE_BEST) {
            https
                    .addParam("best", "1")
                    .addParam("tradeType", "1,2")
                    .addParam("type", "0,1");//如果是精华的话，那就best设置为1
        } else if (currentTradeType == TRADE_TYPE_USER) {
            https
                    .addParam("tradeType", "1")// 1表示分析师晒单或帖子
                    .addParam("type", "1")//1表示帖子，0 表示晒单
                    .addParam("userNo", userNo);
        } else if (currentTradeType == TRADE_TYPE_REPLY) {// 分析师点评
            https
                    .addParam("tradeType", "1,2")
                    .addParam("type", "0,1")// 晒单帖子都要
                    .addParam("userId", userNo);

        } else if (currentTradeType == TRADE_TYPE_ALL_POST) {//动态-查询全部帖子
            https
                    .addParam("type", "1")//1 帖子  // 1-表示帖子，0 表示晒单，这里要返回帖子，所以是1
                    .addParam("tradeType", "1,2"); //1分析师，2客户，查询全部，传1,2
        }

        if (ifSearchUserPost) {// 如果只查詢用戶(包括分析师)的帖子，那麽设置特别参数
            currentTradeType = TRADE_TYPE_MY_POST;
            https
                    .addParam("accountNo", accountNo)//这里参数用6开头的交易账户
                    .addParam("tradeType", "1,2")// 2表示客户,1表示分析师, 这里其实不需要区分。文档上写着，如果不传这个参数，就是查所有，但是实际上，如果不传，就默认为2
                    .addParam("type", "1");//1表示帖子，0 表示晒单，这里要返回帖子，所以是1
        }
        //所有帖子必须都是审核通过的
        https.addParam("status", "1");// 1 表示审核通过

        Log.d("httpParamTag", "url   - " + url);
        //遍历参数
        Map<String, String> map = https.getParam();
        for (Map.Entry<String, String> entry : map.entrySet()) {
            Log.d("httpParamTag", entry.getKey() + ":" + entry.getValue());
        }

        https.get(new Https.ResponseCallback<String>() {
            @Override
            public void onSuccess(Request request, Response response, String result, int code) {
                List<DiscussData> list = parse(result, currPage == 1, userNo);
                if (callBack != null) {
                    callBack.onReqSuccess(list);
                }
            }

            @Override
            public void onFailure(Request request, IOException e) {
                if (callBack != null) {
                    callBack.onReqFailed(e == null ? null : e.getMessage());
                }
            }
        });
    }

    private List<DiscussData> parse(String str, boolean cache, String userNo) {
        Log.d("parseListData", "" + str);
        if (TextUtils.isEmpty(str)) {
            return null;
        }
        try {
            JSONObject jsonObject = new JSONObject(str);
            totalSize = jsonObject.optInt("totalRecords");
            JSONArray dataArr = jsonObject.optJSONArray("data");
            if (dataArr != null && dataArr.length() > 0) {
                List<DiscussData> list = new ArrayList<>();
                for (int i = 0; i < dataArr.length(); i++) {
                    JSONObject itemJson = dataArr.optJSONObject(i);
                    if (itemJson == null) {
                        continue;
                    }
                    DiscussData data = new DiscussData();

                    JSONObject userJson = itemJson.optJSONObject("user");
                    if (userJson != null) {
                        data.accountNo = userJson.optString("accountNo");
                        data.userName = userJson.optString("userName");
                        data.avatar = userJson.optString("avatar");
                        data.clientGroup = userJson.optString("clientGroup");
                        if (userJson.has("userNo"))
                            data.userNo = userJson.optString("userNo");
                    }

                    data.profit = itemJson.optString("profit");//盈利
                    data.id = itemJson.optString("_id");
                    data.createUser = itemJson.optString("createUser");
                    data.showDate = itemJson.optString("showDate");

                    data.tradeImg = itemJson.optString("tradeImg");// 获取图片，单张图
                    data.tradeImgs = itemJson.optString("tradeImgs");// 多张图

                    data.imgSize = itemJson.optString("imgSize");// 图片尺寸，单图
                    data.imgSizes = itemJson.optString("imgSizes");// 图片尺寸，多图

                    data.status = itemJson.optInt("status");
                    data.remark = itemJson.optString("remark");
                    data.praise = itemJson.optInt("praise");
                    data.transmit = itemJson.optInt("transmit");
                    data.tradeType = itemJson.optInt("tradeType");
                    data.type = itemJson.optInt("type");
                    data.sorted = itemJson.optInt("sorted");
                    data.best = itemJson.optInt("best");

                    //在这里，截取comments评论
                    JSONArray array = itemJson.optJSONArray("comments");
                    List<Comment> commentsList = new ArrayList<>();
                    for (int j = 0; j < array.length(); j++) {
                        //逐个解析
                        JSONObject object = array.getJSONObject(j);
                        String userId = object.optString("userId");//分析师id
                        String userName = object.optString("userName");//分析师名字
                        String content = object.optString("content");//评论内容
                        String accountNo = "";
                        if (object.has("accountNo"))
                            accountNo = object.optString("accountNo");//后台缺少这个字段。
                        //回来解决
                        //构建Comment对象，并且加到list中
                        Comment comment = new Comment(userId, accountNo, userName, content);
                        //检查当前评论是不是审核通过的
                        int status = object.optInt("status");
                        if (1 == status)// 只将审核通过的评论加进去
                            commentsList.add(comment);
                    }
                    data.comments = commentsList;
                    list.add(data);
                }
                if (cache) {
                    CacheUtils.writeFile(getCacheFileName(userNo), str);
                }
                return list;
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * @param userNo 如果当前查询的是 分析师帖子和点评，那就要用分析师的no来标识;  其他情况，传null即可
     * @return
     */
    private String getCacheFileName(String userNo) {
        String cacheFileName;
        switch (currentTradeType) {// 根据不同的分类来获取不同的缓存文件名
            case TRADE_TYPE_ALL:
                cacheFileName = CacheUtils.CACHE_HOME_DISCUSS_LIST_FILE;
                break;
            case TRADE_TYPE_ANALYST:
                cacheFileName = CacheUtils.CACHE_HOME_DISCUSS_LIST_FILE_ANALYST;
                break;
            case TRADE_TYPE_GUEST:
                cacheFileName = CacheUtils.CACHE_HOME_DISCUSS_LIST_FILE_GUEST;
                break;
            case TRADE_TYPE_BEST:
                cacheFileName = CacheUtils.CACHE_HOME_DISCUSS_LIST_FILE_BEST;
                break;
            case TRADE_TYPE_USER:
                cacheFileName = userNo + "_" + CacheUtils.CACHE_HOME_DISCUSS_LIST_FILE_USER;//如果是查询分析师的帖子和点评，就必须加入分析师的唯一标识; 正式代码
                Log.d("getCacheFileNameTag", "" + cacheFileName);
//                cacheFileName = CacheUtils.CACHE_HOME_DISCUSS_LIST_FILE;//测试代码，获取的时候，用全部帖子 TODO
                break;
            case TRADE_TYPE_REPLY:
                cacheFileName = userNo + "_" + CacheUtils.CACHE_HOME_DISCUSS_LIST_FILE_REPLY;//如果是查询分析师的帖子和点评，就必须加入分析师的唯一标识
                break;
            case TRADE_TYPE_MY_POST:
                cacheFileName = userNo + "_" + CacheUtils.CACHE_HOME_DISCUSS_LIST_FILE_MY_POST;//我的帖子
                break;
            default:
                cacheFileName = CacheUtils.CACHE_HOME_DISCUSS_LIST_FILE;
                break;
        }
        return cacheFileName;
    }

    /**
     * 点赞
     */
    public void like(String id, final ReqCallBack<String> callBack) {
        String url = ConfigUtil.instance().getHttpUrlIp(ConfigType.CHAT_URL_TAG) + "/api/showTrade/setShowTradePraise";

        new Https().url(url)
                .addParam("praiseId", id)
                .addParam("fromPlatform", ConfigUtil.instance().mConfigObject.optString(ConfigType.CHAT_GROUP_TYPE))
                .addParam("clientId", GTConfig.instance().mCurName)
                .addParam("companyId", ConfigUtil.instance().mConfigObject.optString(ConfigType.CHAT_COMPANY_ID_TAG))
                .addParam("platform", "android")
                .get(new Https.ResponseCallback<String>() {
                    @Override
                    public void onSuccess(Request request, Response response, String result, int code) {
                        String s = parseLike(result);
                        if (callBack != null) {
                            callBack.onReqSuccess(s);
                        }
                    }

                    @Override
                    public void onFailure(Request request, IOException e) {
                        if (callBack != null) {
                            callBack.onReqFailed(e == null ? null : e.getMessage());
                        }
                    }
                });
    }

    /**
     * 转发
     */
    public void transmit(String id, final ReqCallBack<String> callBack) {
        String url = ConfigUtil.instance().getHttpUrlIp(ConfigType.CHAT_URL_TAG) + "/api/showTrade/setShowTradeTransmit";

        new Https().url(url)
                .addParam("transmitId", id)
                .addParam("fromPlatform", ConfigUtil.instance().mConfigObject.optString(ConfigType.CHAT_GROUP_TYPE))
                .addParam("clientId", GTConfig.instance().mCurName)
                .addParam("companyId", ConfigUtil.instance().mConfigObject.optString(ConfigType.CHAT_COMPANY_ID_TAG))
                .addParam("platform", "android")
                .get(new Https.ResponseCallback<String>() {
                    @Override
                    public void onSuccess(Request request, Response response, String result, int code) {
                        String s = parseLike(result);
                        if (callBack != null) {
                            callBack.onReqSuccess(s);
                        }
                    }

                    @Override
                    public void onFailure(Request request, IOException e) {
                        if (callBack != null) {
                            callBack.onReqFailed(e == null ? null : e.getMessage());
                        }
                    }
                });
    }

    public static final String COMMIT_SUCCESS = "COMMIT_SUCCESS";

    private String parseLike(String str) {
        if (TextUtils.isEmpty(str)) {
            return null;
        }
        try {
            JSONObject jsonObject = new JSONObject(str);
            JSONObject dataJson = jsonObject.optJSONObject("data");
            if (dataJson != null) {
                boolean isOK = dataJson.optBoolean("isOK", false);
                if (isOK) {
                    return COMMIT_SUCCESS;
                }
                JSONObject errorJson = dataJson.optJSONObject("error");
                if (errorJson != null) {
                    return errorJson.optString("errmsg");
                }
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return null;
    }

}
